Spring MVC 之 ViewResolver

您所在的位置:网站首页 freemarker springmvc Spring MVC 之 ViewResolver

Spring MVC 之 ViewResolver

#Spring MVC 之 ViewResolver| 来源: 网络整理| 查看: 265

        Spring MVC的视图解析器 ViewResolver 是框架中一个重要的组件,用于将控制器返回的逻辑视图名称解析为具体的视图实现对象,最终呈现给用户的是具体的视图实现,例如 JSP、FreeMarker 模板、Thymeleaf 模板、JSON 等等。本文将介绍 Spring MVC 的视图解析器的作用、类型、以及源码实现。

作用

        在 Spring MVC 中,控制器处理完请求之后需要将生成的模型数据和视图名称返回给 DispatcherServlet,DispatcherServlet 会将模型数据和视图名称交给 ViewResolver 进行解析,ViewResolver 将对应的视图解析出来,并返回给 DispatcherServlet,由 DispatcherServlet 进行渲染,最终将渲染后的结果返回给客户端。因此,ViewResolver 的作用是将控制器返回的逻辑视图名称解析为具体的视图实现对象。

类型

        Spring MVC 中提供了多种 ViewResolver 类型,不同类型的 ViewResolver 会使用不同的解析策略和算法,下面介绍几种常见的 ViewResolver 类型。

InternalResourceViewResolver

        InternalResourceViewResolver 是 Spring MVC 中最常用的视图解析器,它用于解析 JS P或 HTML 等资源文件。该解析器会将逻辑视图名称加上前缀和后缀,例如将逻辑视图名称 “hello” 解析为 “/WEB-INF/views/hello.jsp”。

@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } } 复制代码 FreeMarkerViewResolver

        FreeMarkerViewResolver 用于解析FreeMarker 模板,它会将逻辑视图名称加上前缀和后缀,例如将逻辑视图名称 “hello” 解析为 “/WEB-INF/views/hello.ftl”。

@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public FreeMarkerViewResolver viewResolver() { FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".ftl"); return viewResolver; } } 复制代码 TilesViewResolver

        TilesViewResolver 用于解析 Tiles 布局,它会将逻辑视图名称解析为 Tiles 布局,并返回给 DispatcherServlet 进行渲染。Tiles 是一个基于模板的布局框架,可以将页面分成多个部分,每个部分都是一个独立的模板,最终组合成一个完整的页面。

@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public TilesConfigurer tilesConfigurer() { TilesConfigurer tilesConfigurer = new TilesConfigurer(); tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/tiles.xml" }); return tilesConfigurer; } @Bean public TilesViewResolver viewResolver() { TilesViewResolver viewResolver = new TilesViewResolver(); return viewResolver; } } 复制代码 ContentNegotiatingViewResolver

        ContentNegotiatingViewResolver 是一个复合视图解析器,它可以根据请求的 Accept 头信息来判断客户端需要的数据类型,并选择对应的视图解析器进行解析。例如客户端请求的 Accept 头信息为 “application/json”,则选择使用 MappingJackson2JsonView 解析器将模型数据渲染成 JSON 格式返回给客户端。

@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public ContentNegotiatingViewResolver viewResolver() { ContentNegotiatingViewResolver viewResolver = new ContentNegotiatingViewResolver(); List viewResolvers = new ArrayList(); viewResolvers.add(jsonViewResolver()); viewResolver.setViewResolvers(viewResolvers); return viewResolver; } @Bean public MappingJackson2JsonViewResolver jsonViewResolver() { MappingJackson2JsonViewResolver jsonViewResolver = new MappingJackson2JsonViewResolver(); return jsonViewResolver; } } 复制代码 源码实现

        Spring MVC 中的视图解析器是通过 ViewResolver 接口来实现的,该接口定义了两个方法:

public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; String REDIRECT_URL_PREFIX = "redirect:"; String FORWARD_URL_PREFIX = "forward:"; } 复制代码

        其中,resolveViewName 方法接收一个逻辑视图名称和一个 Locale 对象作为参数,返回一个 View 对象。如果找不到对应的 View 对象,则返回 null。

对于 InternalResourceViewResolver 而言,它的 resolveViewName 方法实现如下:

@Override public View resolveViewName(String viewName, Locale locale) throws Exception { String prefix = getPrefix(); String suffix = getSuffix(); if (viewName.startsWith(REDIRECT_URL_PREFIX)) { String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length()); RedirectView redirectView = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible()); String[] hosts = StringUtils.toStringArray(getRedirectHosts()); if (hosts.length > 0) { redirectView.setHosts(hosts); } return redirectView; } if (viewName.startsWith(FORWARD_URL_PREFIX)) { String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length()); InternalResourceView forwardView = new InternalResourceView(forwardUrl); forwardView.setApplicationContext(getApplicationContext()); forwardView.setServletContext(getServletContext()); forwardView.setAttributesMap(getAttributesMap()); return forwardView; } if (!viewName.startsWith(prefix) && !viewName.endsWith(suffix)) { viewName = prefix + viewName + suffix; } return buildView(viewName); } 复制代码

        在上面的代码中 首先判断逻辑视图名称是否以 redirect: 或 forward: 开头,如果是就返回 RedirectView 或 InternalResourceView 对象。

        如果不是,则根据 prefix 和 suffix 属性将逻辑视图名称转换为物理视图名称。

总结

        Spring MVC 的视图解析器 ViewResolver 是一个重要的组件,它将控制器返回的逻辑视图名称解析为具体的视图实现对象,最终呈现给用户的是具体的视图实现。

        Spring MVC提供了多种 ViewResolver 类型,不同类型的ViewResolver会使用不同的解析策略和算法,例如 InternalResourceViewResolver 用于解析JSP或HTML等资源文件,FreeMarkerViewResolver 用于解析 FreeMarker 模板,TilesViewResolver 用于解析 Tiles 布局,ContentNegotiatingViewResolver 则是一个复合视图解析器,可以根据请求的 Accept 头信息来选择对应的视图解析器进行解析。

        ViewResolver 的源码实现遵循了 ViewResolver 接口的规范,即将逻辑视图名称解析为具体的视图实现对象。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3